package service

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/sirupsen/logrus"
	"hcy-api/lib/jwt"
	"hcy-api/structs/sys"
	"hcy-api/structs/tables"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"sys/global"
	"sys/module/dao"
	"time"
)

var UserServ = new(userService)

type userService struct {
}

func (ser userService) CallVapForAddWinUser(username string) (err error) {
	var (
		bs   []byte
		req  *http.Request
		resp *http.Response
	)
	in := struct {
		Accounts []string `json:"accounts"`
	}{}
	in.Accounts = []string{username}
	bs, err = json.Marshal(in)
	if err != nil {
		return
	}
	for _, uri := range global.Conf.RemoteApi.Vap {
		req, err = http.NewRequest("POST", fmt.Sprintf("%s%s", uri, "/api/vap/remote/createWinRdpAccount"), bytes.NewBuffer(bs))
		if err != nil {
			return
		}
		req.Header.Set("Content-Type", "application/json")
		client := &http.Client{}
		resp, err = client.Do(req)
		if err != nil {
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {
			body, _ := io.ReadAll(resp.Body)
			logrus.Errorf("callVapForAddWinUser http status code %d，err msg :%s", resp.StatusCode, string(body))
		}
	}
	return nil
}

// UserLogin 用户登录，返回token
func (ser userService) UserLogin(loginAccount sys.LoginAccount) (result sys.LoginSuccess, base jwt.BaseClaims, err error) {
	var (
		user         *tables.User
		rs           []string
		accessToken  string
		refreshToken string
	)
	user, err = dao.UserDB.FindUserByAccount(loginAccount.Username)
	if err != nil {
		return
	}
	if user.Password != loginAccount.Password {
		return result, base, fmt.Errorf("密码错误: %v ", loginAccount)
	}
	j := jwt.NewJWT()
	rs = ser.getRoles(user.UserId)
	base = jwt.BaseClaims{
		UserID:    user.UserId,
		Username:  user.Username,
		Nickname:  user.Extend.Nickname,
		AccountLv: user.AccountLv,
		OrgId:     user.OrgId,
		Role:      rs,
	}
	accessToken, err = j.CreateToken(base, jwt.JWTAccessTime)
	refreshToken, err = j.CreateToken(base, jwt.JWTRefreshTime)
	result = sys.LoginSuccess{
		Username:     user.Extend.Nickname,
		Roles:        rs,
		AccessToken:  accessToken,
		RefreshToken: refreshToken,
		Expires:      (time.Now().Unix() + jwt.JWTAccessTime) * 1000,
	}
	return
}

// getRoles 获取角色列表
func (ser userService) getRoles(uid int64) (rs []string) {
	var (
		li  []tables.Role
		err error
	)
	if li, err = dao.UserDB.FindUserRoleList(uid); err != nil {
		return []string{}
	}
	rs = make([]string, len(li))
	for i := range li {
		rs[i] = li[i].RoleCode
	}
	return rs
}

func (ser userService) GetRouterTreeForFile() (bs []byte, err error) {
	var (
		p string
	)
	if p, err = os.Executable(); err != nil {
		logrus.Error("os.Executable()", p, err)
		return
	}
	return os.ReadFile(filepath.Join(filepath.Dir(p), "web_router.json"))
}

// VerifyCode 检查验证码是否合法
func (ser userService) VerifyCode(ver sys.VeryCode) bool {
	return true
}

// CheckUpdateUserAuthority 检查是否有权限对改用户执行更新操作
func (ser userService) CheckUpdateUserAuthority(tar *tables.User, self *jwt.CustomClaims) (b bool) {
	if self.AccountLv == tables.AccountLvForRoot {
		return true
	}
	if tar.CreatorId == self.UserID {
		return true
	}
	return false
}

func (ser userService) GetUserList(uid int64, accountLv int) (li []tables.User, err error) {
	if accountLv == tables.AccountLvForRoot {
		li, err = dao.UserDB.FindList()
	} else {
		var orgIds []int64
		orgIds, err = dao.UserDB.FindOrgIds(uid)
		if err != nil {
			li = make([]tables.User, 0)
		} else {
			li, err = dao.UserDB.FindListByOrgIds(orgIds)
		}
	}
	return
}
